﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using MoreEPG.Helper;
using MoreEPG.Data;
using MoreEPG.DataAccess;
using MoreEPG.Model;
using Microsoft.MediaCenter.Store;
using MCHelp;
using System.Diagnostics;

namespace MoreEPG
{
    /// <summary>
    /// Singleton Core Class
    /// </summary>
    public sealed class Core
    {
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        private bool updateDB = false;
        private bool loadInMC = false;
        private bool writeToFile = false;
        private bool reindex = false;

        static readonly Core _instance = new Core();
        /// <summary>
        /// Returns the Core Instance
        /// </summary>
        public static Core Instance
        {
            get { return _instance; }
        }


        private Dispatcher _UiDisp;
        /// <summary>
        /// Get or Set the UI Dispatcher
        /// </summary>
        public Dispatcher UiDisp
        {
            get
            {
                return this._UiDisp;
            }
            set
            {
                this._UiDisp = value;
            }
        }

        private Delegate _UpdateProgressdelegate;
        /// <summary>
        /// Get or Set the Progress Delegate
        /// </summary>
        public Delegate UpdateProgressdelegate 
        {
            get
            {
                return this._UpdateProgressdelegate;
            }
            set
            {
                this._UpdateProgressdelegate = value;
            }
        }

        private Delegate _MxfProgressdelegate;
        /// <summary>
        /// Get or Set the Progress Delegate (Special for MXFWriter)
        /// </summary>
        public Delegate MxfProgressdelegate
        {
            get
            {
                return this._MxfProgressdelegate;
            }
            set
            {
                this._MxfProgressdelegate = value;
            }
        }

        private MCConnection _MCCon;
        /// <summary>
        /// Get the MCCoonection
        /// </summary>
        public MCConnection MCCon
        {
            get
            {
                if (this._MCCon == null)
                {
                    try
                    {
                        this._MCCon = new MCConnection();
                    }
                    catch (Exception ex)
                    {
                        logger.ErrorException("Initilize MCConnection failed.", ex);
                        return null;
                    }
                }
                return this._MCCon;
            }
        }

        private ObjectStore _Store;
        /// <summary>
        /// Get the MC ObjectStore
        /// </summary>
        public ObjectStore Store
        {
            get
            {
                if (this._Store == null)
                {
                    try
                    {
                        this._Store = this._MCCon.Store;
                    }
                    catch (Exception ex)
                    {
                        logger.ErrorException("Initialize ObjectStore failed.", ex);
                        return null;
                    }
                }
                return this._Store;
            }

        }
        
        private Datas _Datas;
        private MXFWriter _MXFWriter;

        private Core()
        {
            
        }

        private void Initialize()
        {
            logger.Debug("Initialize starts");
            if (this._UiDisp == null && this._UpdateProgressdelegate == null && this._MxfProgressdelegate == null)
            {
                logger.Error("Dispatcher and Delegates are null!");
                throw new ApplicationException("Dispatcher and Delegates are null!");
            }

            updateDB = Properties.Settings.Default.UpdateDB;
            reindex = Properties.Settings.Default.Reindex;
            string[] args = Environment.GetCommandLineArgs();
            if (Properties.Settings.Default.LoadEPG)
            {
                loadInMC = true;
            }
            else
            {
                writeToFile = true;
            }
            if (args.Contains("-debug") || args.Contains("-Debug"))
            {
                writeToFile = true;
            }

            if (this._Datas == null)
            {
                this._Datas = new Datas(this._UiDisp, this._UpdateProgressdelegate);
            }
            if (this._MXFWriter == null)
            {
                this._MXFWriter = new MXFWriter(this._UiDisp, this._MxfProgressdelegate);
            }
            logger.Debug("Initialize finished");
        }

        /// <summary>
        /// Do All the Magic Work
        /// </summary>
        public void DoAll()
        {
            Initialize();
            if (updateDB)
            {
                logger.Debug("DB starts to Update."); 
                this._Datas.UpdateSource();
                logger.Debug("DB finished to Update."); 
            }
            logger.Debug("Datas starts to load."); 
            this._Datas.FillDatas();
            
            this._Datas.FillCollections();
            logger.Debug("Datas finished to load."); 

            this._MXFWriter.Results = this._Datas.Results;

            logger.Debug("MXFWriter starts."); 
            this._MXFWriter.Write(loadInMC, writeToFile);
            logger.Debug("MXFWriter stops."); 
            if (reindex)
            {
                logger.Debug("Reindex starts."); 
                this.ReIndex();
                logger.Debug("Reindex stops."); 
            }
            
        }

        /// <summary>
        /// Returns the MC Channels
        /// </summary>
        /// <returns></returns>
        public MCChannelInfoCollection GetMCChannels()
        {
            Initialize();
            return this._Datas.GetMCChannels();
        }

        /// <summary>
        /// Returns the Source Channels
        /// </summary>
        /// <returns></returns>
        public TVChannelCollection GetTVChannels()
        {
            Initialize();
            return this._Datas.GetTVProgramms();
        }

        /// <summary>
        /// Start Reindex
        /// </summary>
        private void ReIndex()
        {
            string schtask = Environment.GetEnvironmentVariable("windir") + @"\system32\schtasks.exe";
            logger.Debug("Reindex Task wird gestartet");
            Process proc = new Process();
            ProcessStartInfo Startinfo = new ProcessStartInfo(schtask);
            Startinfo.Arguments = " /run /tn \"\\Microsoft\\Windows\\Media Center\\ReindexSearchRoot\"";
            Startinfo.CreateNoWindow = true;
            Startinfo.WindowStyle = ProcessWindowStyle.Hidden;
            proc.StartInfo = Startinfo;
            proc.Start();
            proc.WaitForExit();
            logger.Debug("Reindex Task ist Fertig");
        }
    }
}
